﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace Duckbill
{
    public class RoomTransition : GameObject
    {
        public Room newRoom;
        public Vector2 newPos;
        public TransitionType direction;

        public RoomTransition(Vector2 pos, Vector2 size, Room newRoom,
            Vector2 newPos, TransitionType direction)
            : base("null", pos)
        {
            type = ObjectType.transition;
            sprite.size = size;
            this.newRoom = newRoom;
            this.newPos = newPos;
            this.direction = direction;
        }

        //TODO: EmptyObject from GameObject that does neither of these
        public override void Draw(SpriteBatch batch) { return; }
        public override void Move(float time) { return; }
    }

    public class Room
    {
        public int X, Y; //position of Room in Map
        public int W, H; //grid dimensions of Room

        public int[,] intTiles;
        public Tile[,] tiles;
        public List<RoomTransition> transitions = new List<RoomTransition>();
        public List<Room> neighbors = new List<Room>();
        public Vector2 camera = Vector2.Zero;
        public Vector2 Camera
        {
            get { return camera; }
        }

        public int spriteW;
        public int spriteH;

        public Room(int X, int Y, int W, int H, int spriteW=32, int spriteH=32)
        {
            this.X = X;
            this.Y = Y;
            this.W = W;
            this.H = H;
            this.spriteW = spriteW;
            this.spriteH = spriteH;

            int w = W * (Game.SCREEN_WIDTH/spriteW);
            int h = H * (Game.SCREEN_HEIGHT/spriteH);
            int[,] tiles = new int[w, h];
            for (int i = 0; i < w; i++)
                tiles[i, 0] = tiles[i, h-1] = 2;
            for (int j = 1; j < h-1; j++)
                tiles[0, j] = tiles[w-1, j] = 2;

            w = (Game.SCREEN_WIDTH/spriteW);
            h = (Game.SCREEN_HEIGHT/spriteH);
            for (int x = 0; x < W; x++)
                for (int y = 0; y < H; y++)
                {
                    for (int i = 0; i < 6; i++)
                        tiles[i+7 + w*x, 7 + h*y] = 2;
                    for (int i = 0; i < 3; i++)
                    {
                        tiles[i+4 + w*x, h*(y+1)-1] = 2;
                        tiles[i+13 + w*x, h*(y+1)-1] = 2;
                    }
                }

            SetTiles(tiles);
        }

        public void SetTiles(int[,] tiles)
        {
            this.intTiles = tiles;

            int roomW = tiles.GetLength(0);
            int roomH = tiles.GetLength(1);
            this.tiles = new Tile[roomW, roomH];
            for (int i = 0; i < roomW; i++)
                for (int j = 0; j < roomH; j++)
                {
                    this.tiles[i, j] = new Tile(tiles[i, j],
                        new Vector2(i * spriteW, j * spriteH));
                    this.tiles[i, j].room = this;
                }
        }

        public List<GameObject> GetObjectsList()
        {
            List<GameObject> L = new List<GameObject>();
            foreach (Tile tile in tiles)
            {
                if (tile.tileType == TileType.enemySpawn)
                {
                    Enemy E = new Enemy("enemy", 10, new Vector2(tile.pos.X, tile.pos.Y));
                    E.room = this;
                    L.Add(E);
                }
                else if (tile.tileType != TileType.empty)
                {
                    L.Add(tile);
                }
            }
            foreach (RoomTransition trans in transitions)
            {
                L.Add(trans);
            }
            return L;
        }

        public void AddTransition(RoomTransition trans)
        {
            transitions.Add(trans);
        }

        public int Width { get { return tiles.GetLength(0)*spriteW; } }
        public int Height { get { return tiles.GetLength(1)*spriteH; } }

        public void UpdateCamera(Vector2 pos, float time)
        {
            int roomW = tiles.GetLength(0)*spriteW;
            int roomH = tiles.GetLength(1)*spriteH;
            int leftBound = Game.SCREEN_WIDTH/3;
            int rightBound = Game.SCREEN_WIDTH*2/3;
            int topBound = Game.SCREEN_HEIGHT/3;
            int bottomBound = Game.SCREEN_HEIGHT*2/3;

            if (pos.X-camera.X < leftBound)
                camera.X = pos.X - leftBound;
            else if (pos.X-camera.X > rightBound)
                camera.X = pos.X - rightBound;
            if (pos.Y-camera.Y < topBound)
                camera.Y = pos.Y - topBound;
            else if (pos.Y-camera.Y > bottomBound)
                camera.Y = pos.Y - bottomBound;

            camera.X = MathHelper.Clamp(camera.X, 0, roomW-Game.SCREEN_WIDTH);
            camera.Y = MathHelper.Clamp(camera.Y, 0, roomH-Game.SCREEN_HEIGHT);
        }
        public void Draw(SpriteBatch batch)
        {
            foreach (Tile tile in tiles)
                if (tile.tileType != TileType.empty && 
                    tile.tileType != TileType.enemySpawn)
                    tile.Draw(batch);
        }
    }
}
